package com.cyt.work.wb.service.impl;

import cn.afterturn.easypoi.excel.entity.result.ExcelImportResult;
import cn.hutool.core.date.DateUtil;
import com.cyt.base.model.dto.ReturnResult;
import com.cyt.base.util.*;
import com.cyt.sys.dao.SysFileDao;
import com.cyt.sys.model.po.SysFile;
import com.cyt.sys.util.EasyPoiUtil;
import com.cyt.sys.util.FilePathUtil;
import com.cyt.work.util.cache.ListToMapUtil;
import com.cyt.work.wb.dao.*;
import com.cyt.work.wb.model.po.*;
import com.cyt.work.wb.model.vo.*;
import com.cyt.work.wb.service.WbDevicesService;
import com.cyt.sys.model.po.SysUser;
import com.cyt.sys.service.impl.BaseServiceImpl;
import com.cyt.work.wb.service.WxWbRoomService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.iherus.codegen.qrcode.SimpleQrcodeGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.*;

/**
 * 维保模块-设备表Service层实现类
 *
 * @author shengQiang Yu
 * @date 2019-11-28 9:26:43
 */
@Service("wbDevicesService")
public class WbDevicesServiceImpl extends BaseServiceImpl<WbDevices> implements WbDevicesService {

    @Resource
    private WbDevicesDao wbDevicesDao;

    @Resource
    private SysFileDao sysFileDao;

    @Resource
    private WxWbRoomDao wxWbRoomDao;

    @Resource
    private WbDevicesTypeDao  wbDevicesTypeDao;

    @Resource
    private WbServicerDao wbServicerDao;

    @Resource
    private WbContractDao wbContractDao;

    @Autowired
    public void setBaseDao(WbDevicesDao wbDevicesDao) {
        this.baseDao = wbDevicesDao;
    }

    /**
     * 查询对象集合
     *
     * @param wbDevicesVo 对象
     * @return List 对象集合
     * @author shengQiang Yu
     * @date 2019-11-28 9:26:43
     */
    @Override
    public List<WbDevices> listExample(WbDevicesVo wbDevicesVo) {
        Example example = new Example(WbDevices.class);
        example.setOrderByClause(" create_time desc");
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("removeTag", DictCode.BASE_REMOVE_TAG_NORMAL);
        return wbDevicesDao.selectByExample(example);
    }

    /**
     * 分页查询
     *
     * @param wbDevicesVo 接受参数对象
     * @param pageNum          分页数
     * @param pageSize         每页显示条数
     * @return ReturnResult
     * @author shengQiang Yu
     * @date 2019-11-28 9:26:43
     */
    @Override
    public ReturnResult page(WbDevicesVo wbDevicesVo, int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        PageHelper.orderBy(" create_time desc");
        List<WbDevices> list = selectByCondition(wbDevicesVo);
        PageInfo<WbDevices> page = new PageInfo<>(list);
        return new ReturnResult(page.getList(), page.getTotal(), page.isHasNextPage());
    }

    @Override
    public WbDevices findById(String id) {
        WbDevicesVo wbDevicesVo =new WbDevicesVo();
        wbDevicesVo.setId(id);
        return wbDevicesDao.selectByCondition(wbDevicesVo).get(0);
    }

    /**
     * 添加或更新
     *
     * @param wbDevicesVo 参数接受对象
     * @param sysUser      当前用户
     * @return ReturnResult
     * @author shengQiang Yu
     * @date 2019-11-28 9:26:43
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ReturnResult addOrUpdate(HttpServletRequest request,WbDevicesVo wbDevicesVo, SysUser sysUser) {
        if (StringUtils.isBlank(wbDevicesVo.getId())) {
            WbDevices wbDevices = new WbDevices(sysUser);
            wbDevices.setApplyId(wbDevicesVo.getApplyId());
            wbDevices.setName(wbDevicesVo.getName());
            wbDevices.setNum(wbDevicesVo.getNum());
            wbDevices.setDeviceTypeId(wbDevicesVo.getDeviceTypeId());
            wbDevices.setDeviceCategory(wbDevicesVo.getDeviceCategory());
            wbDevices.setDeviceModel(wbDevicesVo.getDeviceModel());
            wbDevices.setRoomId(wbDevicesVo.getRoomId());
            wbDevices.setProducedDate(DateUtil.parseDate(wbDevicesVo.getProducedDate()));
            wbDevices.setBuyDate(DateUtil.parseDate(wbDevicesVo.getBuyDate()));
            wbDevices.setMaintenanceDate(DateUtil.parseDate(wbDevicesVo.getMaintenanceDate()));
            wbDevices.setDurableTime(wbDevicesVo.getDurableTime());
            wbDevices.setServicerId(wbDevicesVo.getServicerId());
            wbDevices.setContractId(wbDevicesVo.getContractId());
            wbDevices.setTwoDimension(getQrCode(request,wbDevices.getId(),sysUser.getId()));
            wbDevices.setRemarks(wbDevicesVo.getRemarks());
            wbDevices.setSort(Integer.parseInt(wbDevicesVo.getSort()));
            wbDevicesDao.insert(wbDevices);
            return new ReturnResult(BaseConstant.DATABASE_SUCCEED_INSERT);
        } else {
            WbDevices wbDevices = wbDevicesDao.selectByPrimaryKey(wbDevicesVo.getId());
            wbDevices.setApplyId(wbDevicesVo.getApplyId());
            wbDevices.setName(wbDevicesVo.getName());
            wbDevices.setNum(wbDevicesVo.getNum());
            wbDevices.setDeviceTypeId(wbDevicesVo.getDeviceTypeId());
            wbDevices.setDeviceCategory(wbDevicesVo.getDeviceCategory());
            wbDevices.setDeviceModel(wbDevicesVo.getDeviceModel());
            wbDevices.setRoomId(wbDevicesVo.getRoomId());
            wbDevices.setProducedDate(DateUtil.parseDate(wbDevicesVo.getProducedDate()));
            wbDevices.setBuyDate(DateUtil.parseDate(wbDevicesVo.getBuyDate()));
            wbDevices.setMaintenanceDate(DateUtil.parseDate(wbDevicesVo.getMaintenanceDate()));
            wbDevices.setDurableTime(wbDevicesVo.getDurableTime());
            wbDevices.setServicerId(wbDevicesVo.getServicerId());
            wbDevices.setContractId(wbDevicesVo.getContractId());
            wbDevices.setTwoDimension(getQrCode(request,wbDevices.getId(),sysUser.getId()));
            wbDevices.setRemarks(wbDevicesVo.getRemarks());
            wbDevices.setSort(Integer.parseInt(wbDevicesVo.getSort()));
            wbDevices.setUpdateTime(new Date());
            wbDevices.setUpdateUser(sysUser.getId());
            wbDevicesDao.updateByPrimaryKey(wbDevices);
            return new ReturnResult(BaseConstant.DATABASE_SUCCEED_UPDATE);
        }
    }

    /**
     * 根据条件逻辑删除
     *
     * @param wbDevicesVo 参数接受对象
     * @param sysUser 当前用户
     * @return ReturnResult
     * @author shengQiang Yu
     * @date 2019-11-28 9:26:43
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ReturnResult remove(WbDevicesVo wbDevicesVo, SysUser sysUser) {
        //要修改的字段
        WbDevices wbDevices = new WbDevices();
        wbDevices.setRemoveTag(DictCode.BASE_REMOVE_TAG_DELETE);
        wbDevices.setUpdateUser(sysUser.getId());
        wbDevices.setUpdateTime(new Date());
        //筛选条件
        Example example = new Example(WbDevices.class);
        Example.Criteria criteria = example.createCriteria();
        if (StringUtils.isNotBlank(wbDevicesVo.getId())) {
            criteria.andIn("id", Arrays.asList(wbDevicesVo.getId().split(",")));
        }
        criteria.andEqualTo("removeTag", DictCode.BASE_REMOVE_TAG_NORMAL);
        wbDevicesDao.updateByExampleSelective(wbDevices, example);
        return new ReturnResult(ErrorCode.CODE_0, BaseConstant.DATABASE_SUCCEED_DEL);
    }

    /**
     * 根据条件物理删除
     *
     * @param wbDevicesVo 参数接受对象
     * @param sysUser      当前用户
     * @return ReturnResult
     * @author shengQiang Yu
     * @date 2019-11-28 9:26:43
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ReturnResult delete(WbDevicesVo wbDevicesVo, SysUser sysUser) {
        //筛选条件
        Example example = new Example(WbDevices.class);
        Example.Criteria criteria = example.createCriteria();
        if (StringUtils.isNotBlank(wbDevicesVo.getId())) {
            criteria.andIn("id", Arrays.asList(wbDevicesVo.getId().split(",")));
        }
        wbDevicesDao.deleteByExample(example);
        return new ReturnResult(ErrorCode.CODE_0, BaseConstant.DATABASE_SUCCEED_DEL);
    }

    /**
     * 查询集合
     *
     * @param wbDevicesVo
     * @return
     * @author shengQiang yu
     * @date 2019-11-29 11:52
     */
    public List<WbDevices> selectByCondition(WbDevicesVo wbDevicesVo){
        return wbDevicesDao.selectByCondition(wbDevicesVo);
    }

    @Override
    public ReturnResult importExcel(HttpServletRequest request, MultipartFile file, SysUser sysUser, String applyId) {
        ExcelImportResult<WbDevicesExportVo> result = EasyPoiUtil.importExcelResult(file, 1, 1, WbDevicesExportVo.class);
        List<WbDevicesExportVo> WbDevicesExportVoList =  result.getList();
        //获取合同列表
        Map<String,String> contractMaps=ListToMapUtil.listMaptoMap(wbContractDao.selectToHashMap(new WbContractVo(applyId)));
        //获取服务商列表
        Map<String,String> wbServicerMaps=ListToMapUtil.listMaptoMap(wbServicerDao.selectToHashMap(new WbServicerVo(applyId)));
        //获取设备分类列表
        Map<String,String> wbDevicesTypeMaps=ListToMapUtil.listMaptoMap(wbDevicesTypeDao.selectToHashMap(new WbDevicesTypeVo(applyId)));
        //获取场所列表
        Map<String,String> wbRoomMaps=ListToMapUtil.listMaptoMap(wxWbRoomDao.selectToHashMap(new WxWbRoomVo(applyId)));
        List<WbDevices> wbDevicesList=new ArrayList<WbDevices>();
        List<String> ids=new ArrayList<String>();//设备id
        for(WbDevicesExportVo wbDevicesExportVo:WbDevicesExportVoList){
            WbDevices wbDevices = new WbDevices(sysUser);
            wbDevices.setApplyId(applyId);
            wbDevices.setName(wbDevicesExportVo.getName());
            wbDevices.setNum(wbDevicesExportVo.getNum());
            //设置分类
            wbDevices.setDeviceTypeId(wbDevicesTypeMaps.get(wbDevicesExportVo.getDeviceTypeId()));
            wbDevices.setDeviceCategory(wbDevicesExportVo.getDeviceCategory());
            wbDevices.setDeviceModel(wbDevicesExportVo.getDeviceModel());
            //设置房间id
            wbDevices.setRoomId(wbRoomMaps.get(wbDevicesExportVo.getRoomId()));
            wbDevices.setProducedDate(DateUtil.parseDate(wbDevicesExportVo.getProducedDate()));
            wbDevices.setBuyDate(DateUtil.parseDate(wbDevicesExportVo.getBuyDate()));
            wbDevices.setMaintenanceDate(DateUtil.parseDate(wbDevicesExportVo.getMaintenanceDate()));
            wbDevices.setDurableTime(wbDevicesExportVo.getDurableTime());
            //设置服务商
            wbDevices.setServicerId(wbServicerMaps.get(wbDevicesExportVo.getServicerId()));
            //设置合同
            wbDevices.setContractId(contractMaps.get(wbDevicesExportVo.getContractId()));
            wbDevices.setTwoDimension(getQrCode(request,wbDevices.getId(),sysUser.getId()));
            wbDevices.setRemarks(wbDevicesExportVo.getRemarks());
            wbDevices.setSort(Integer.parseInt(wbDevicesExportVo.getSort()));
            wbDevicesList.add(wbDevices);
            ids.add(wbDevices.getId());
        }
          wbDevicesDao.insertList(wbDevicesList);

        if (result.isVerfiyFail()) {
            // 如果错误，打印出提醒，直接返回
            int successNum = 0;
            int failNum = result.getFailList().size();
            if (result.getList() != null && result.getList().size() > 0) {
                successNum = result.getList().size();
            }
            String errorMsg = String.format("共导入%s条，成功%s条，失败%s条。", successNum + failNum, successNum, failNum);
            List<WbDevicesExportVo> failList = result.getFailList();
            // 需要将成功条数也返回
            Map<String, Object> resutlMap = new HashMap<>();
            resutlMap.put("failList", failList);
            return new ReturnResult(ErrorCode.CODE_1, resutlMap, errorMsg);
            //return new ReturnResult(wxEducationUserShow);
        }
        int successNumber =0;
        if (result.getList() != null && result.getList().size() > 0) {
            successNumber = result.getList().size();
        }
        String sucess = String.format("共导入%s条，成功%s条，失败0条。", successNumber, successNumber);
        return new ReturnResult(ErrorCode.CODE_0,"" , sucess);
    }


    private String getQrCode(HttpServletRequest request, String id,String memId) {
        String qrCode = "";
        // String getContextPath = request.getContextPath();
        // String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + getContextPath + "/";
        String realPath = FilePathUtil.acceptCheckRealPath(request);
        String path = realPath + "/upload/devices/" + id + ".png";
        File dicFile = new File(realPath + "/upload/devices/");
        if  (!dicFile .exists()  && !dicFile .isDirectory()) {
            dicFile .mkdir();
        }
        try {
            File file = new File(path);
            if (file.exists()) {
                // 删除问卷，重新生成
                file.delete();
            }
            OutputStream out = new FileOutputStream(path);
            new SimpleQrcodeGenerator().generate(id+"&"+"2").toStream(out);//设备type为2
           //添加到附件列表
            String fileName = id;
            //文件类型
            String type = BaseUtil.acceptFileType(fileName);
            SysFile sysFile = new SysFile();
            sysFile.setId(BaseUtil.uId());
            sysFile.setFileName(fileName);
            sysFile.setExtendName(type);
            sysFile.setObjectId(StringUtils.isNotEmpty(id) ? id : BaseUtil.uId());
            sysFile.setStorageType(DictCode.STORAGE_TYPE_LOCALHOST);
            sysFile.setPath("/upload/devices/" + id + ".png");
            sysFile.setType("devices");
            sysFile.setCreatorId(memId);
            sysFile.setRemoveTag(DictCode.BASE_REMOVE_TAG_NORMAL);
            sysFile.setCreateTime(new Date());
            //插入到数据库
            //删除原文件
            SysFile sysFileSearch=new SysFile();
            sysFileSearch.setObjectId(sysFile.getObjectId());
            List<SysFile> sysFiles=sysFileDao.select(sysFileSearch);
            if(sysFiles.size()>0){
                for(SysFile s:sysFiles){
                    sysFileDao.delete(s);
                }
            }
             sysFileDao.insert(sysFile);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return id;
    }
}